package com.jw.blog.wblog.controller.admin;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jw.blog.annotation.SystemLog;
import com.jw.blog.utils.ConstantUtil;
import com.jw.blog.utils.SubStringUtil;
import com.jw.blog.wblog.entity.Blog;
import com.jw.blog.wblog.entity.BlogType;
import com.jw.blog.wblog.entity.custom.ResultBean;
import com.jw.blog.wblog.entity.custom.TimeAndCount;
import com.jw.blog.wblog.service.IBlogService;

import com.jw.blog.wblog.service.IBlogTypeService;
import lombok.Data;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author wan Email-wlf18726994755@163.com
 * @version 1.0
 * @className BlogControllerAdmin
 * @date 2020/6/21 15:05
 **/
@RestController
public class BlogControllerAdmin {

    @Data
    static
    class sc implements Serializable {
        private static final long serialVersionUID = 1L;
        //写个注释吧，不写我怕我自己也记不住，害，这是个啥来着，
        // 容我。组织一下语言，这个内部类的一个属性，妈耶你这不是废话么。
        //状态标签，1为正文，-1为草稿，2为回收站
        private Integer status;
        //不同状态的博客数量
        private Integer count;
    }

    @Resource
    private IBlogService iBlogService;

    @Resource
    private IBlogTypeService iBlogTypeService;

    @GetMapping("/admin/selectBlogListByStatus")
//    @AccessLimit(seconds = 1, maxCount = 10)
    public ResultBean<List<sc>> selectBlogListByStatus() {
        QueryWrapper<Blog> blogQueryWrapper;
        ArrayList<sc> scs = new ArrayList<>();
        ResultBean<List<sc>> resultBean = new ResultBean<>();
        for (int i = -1; i < 3; i++) {
            blogQueryWrapper = new QueryWrapper<>();
            if (i == 0) {
                continue;
            }
            blogQueryWrapper.lambda().eq(Blog::getStatus, i).select(Blog::getStatus);
            List<Blog> list = iBlogService.list(blogQueryWrapper);
            sc blogsc = new sc();
            blogsc.setStatus(i);
            blogsc.setCount(list.size());
            scs.add(blogsc);
        }
        resultBean.setData(scs);
        return resultBean;
    }

    @GetMapping("/admin/selectBlogListByDate")
//    @AccessLimit(seconds = 1, maxCount = 10)
    public ResultBean<List<TimeAndCount>>  selectBlogListByDate(
            @RequestParam(value = "startTime") String startTime,
            @RequestParam(value = "endTime") String endTime,
            @RequestParam(value = "status") String status
    ) {
        Map<String, Object> map = new HashMap<>();
        if (!StrUtil.hasEmpty(status)) {
            map.put("status", status);
        }
        if (!StrUtil.hasEmpty(startTime)) {
            map.put("startTime", startTime);
        }
        if (!StrUtil.hasEmpty(endTime)) {
            map.put("endTime", endTime);
        }
        ResultBean<List<TimeAndCount>> resultBean = new ResultBean<>();
        List<TimeAndCount> timeAndCounts = iBlogService.selectBlogListByDate(map);
        if (timeAndCounts.size() != 0){
            resultBean.setCode(ResultBean.SUCCESS);
            resultBean.setData(timeAndCounts);
        }else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    @GetMapping("/admin/selectBlogByClick")
    public ResultBean<List<Blog>> selectBlogByClick() {
        QueryWrapper<Blog> blogQueryWrapper = new QueryWrapper<>();
        blogQueryWrapper.lambda().orderByDesc(Blog::getClickNum);
        blogQueryWrapper.lambda().select(Blog::getId, Blog::getClickNum);
        //查询七个
        Page<Blog> blogPage = new Page<>();
        blogPage.setCurrent(1);
        blogPage.setSize(7);
        Page<Blog> page = iBlogService.page(blogPage, blogQueryWrapper);
        List<Blog> records = page.getRecords();
        ResultBean<List<Blog>> resultBean = new ResultBean<>();
        if (records.size() != 0){
            resultBean.setCode(ResultBean.SUCCESS);
            resultBean.setData(records);
        }else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }


    @PostMapping("/admin/selectBlogType")
    public ResultBean<List<BlogType>> selectBlogType(@RequestParam(value = "data", required = false) String data) {
        ResultBean<List<BlogType>> resultBean = new ResultBean<>();
        if ("all".equals(data)) {
            List<BlogType> list = iBlogTypeService.list();
            if (list.size() != 0){
                resultBean.setCode(ResultBean.SUCCESS);
                resultBean.setData(list);
            }else {
                resultBean.setCode(ResultBean.FAIL);
            }
        } else {
            List<BlogType> list = iBlogTypeService.list();
            if (list.size() != 0){
                resultBean.setCode(ResultBean.SUCCESS);
                resultBean.setData(list);
            }else {
                resultBean.setCode(ResultBean.FAIL);
            }
        }
        return resultBean;
    }


    @GetMapping("/admin/selectLikeBlogListByPage")
//    @AccessLimit(seconds = 1, maxCount = 13)
    public ResultBean<IPage<Blog>> selectLikeBlogListByPage(Blog blog,
                                                @RequestParam(value = "sort", required = true, defaultValue = "addTime")
                                                        String sort,
                                                @RequestParam(value = "page", required = true, defaultValue = "1")
                                                        Integer page,
                                                @RequestParam(value = "pageSize", required = true, defaultValue = "10")
                                                        Integer pageSize
    ) {
        QueryWrapper<Blog> blogQueryWrapper = listMap(blog, sort);
        //分页数据
        Page<Blog> blogPage = new Page<>();
        blogPage.setCurrent(page);
        blogPage.setSize(pageSize);
        Page<Blog> page1 = iBlogService.page(blogPage, blogQueryWrapper);
        ResultBean<IPage<Blog>> resultBean = new ResultBean<>();
        if (page1.getRecords().size() != 0){
            resultBean.setCode(ResultBean.SUCCESS);
            resultBean.setData(page1);
        }else {
            resultBean.setCode(ResultBean.FAIL);
            resultBean.setMsg("数据为空");
        }
        return resultBean;

    }


    /**
     * 分组查询博客信息，不包括博客内容
     *
     * @param blog     博客实体类属性
     * @param sort     排序规则
     * @param page     当前页
     * @param pageSize 一页几条内容
     * @return 返回数据包括分页数据
     */
    @PostMapping("/admin/selectGroupLikeBlogListByPage")
//    @AccessLimit(seconds = 1, maxCount = 15)
    public ResultBean<IPage<Blog>> selectGroupLikeBlogListByPage(
            Blog blog,
            @RequestParam(value = "sort", defaultValue = "addTime") String sort,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize
    ) {
        QueryWrapper<Blog> blogQueryWrapper = listMap(blog, sort);
        //排除博客内容content
        blogQueryWrapper.select(Blog.class, i -> !"content".equals(i.getColumn()));
        //分页显示
        IPage<Blog> iPage = new Page<>();
        iPage.setCurrent(page);
        iPage.setSize(pageSize);
        IPage<Blog> page1 = iBlogService.page(iPage, blogQueryWrapper);
        List<Blog> records = page1.getRecords();
        for (Blog record : records) {
            for (BlogType blogType : getType()) {
                if (record.getTypeId().equals(Integer.toString(blogType.getId()))) {
                    record.setTypeId(blogType.getTypeName());
                }
            }
        }
        page1.setRecords(records);
        ResultBean<IPage<Blog>> resultBean = new ResultBean<>();
        resultBean.setData(page1);
        resultBean.setCode(ResultBean.SUCCESS);
        return resultBean;
    }


    /**
     * 更新博客功能
     *
     * @param blog 封装的属性
     * @return 返回一个值，具体待定
     */
    @PostMapping("/admin/updateBlog")
    @SystemLog(description = ConstantUtil.BLOG_UPDATE, userType = ConstantUtil.USERTYPE_ADMIN)
    public ResultBean<Object> updateBlog(String prarm, Blog blog) {
        // 将中文的分号转换成英文的分号
        if (!StrUtil.hasEmpty(blog.getKeyword())) {
            blog.setKeyword(SubStringUtil.subKeyword(blog.getKeyword()));
        }
        ResultBean<Object> resultBean = new ResultBean<>();
        if (iBlogService.updateById(blog)) {
            resultBean.setCode(ResultBean.SUCCESS);
            resultBean.setMsg("更新成功");
            blogTypeCount();
        } else {
            // 0表示：更新失败
            resultBean.setCode(ResultBean.FAIL);
            resultBean.setMsg("更新失败");
        }
        return resultBean;
    }


    @PostMapping("/admin/selectBlogById")
    public ResultBean<Blog> selectBlogById(@RequestParam(value = "id") Integer id) {
        Blog byId = iBlogService.getById(id);

        for (BlogType blogType : getType()) {
            if (byId.getTypeId().equals(Integer.toString(blogType.getId()))) {
                byId.setTypeId(byId.getTypeId() + "=" + blogType.getTypeName());
            }
        }
        ResultBean<Blog> resultBean = new ResultBean<>();
        if (ObjectUtil.isNotNull(byId)){
            resultBean.setData(byId);
        }else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    /**
     * 工具方法
     *
     * @param blog 传入的博客属性
     * @param sort 排序方式
     * @return 返回条件构造器
     */
    public static QueryWrapper<Blog> listMap(Blog blog, String sort) {

        QueryWrapper<Blog> blogQueryWrapper = new QueryWrapper<>();
        if (!StrUtil.hasEmpty(blog.getTitle())) {
            blogQueryWrapper.lambda().like(Blog::getTitle, blog.getTitle()).or();
        }

        if (!StrUtil.hasEmpty(blog.getIntroduction())) {
            blogQueryWrapper.lambda().like(Blog::getIntroduction, blog.getIntroduction()).or();
        }

        if (!StrUtil.hasEmpty(blog.getKeyword())) {
            blogQueryWrapper.lambda().like(Blog::getKeyword, blog.getKeyword());
        }

        if (blog.getIsTop() != null) {
            blogQueryWrapper.lambda().eq(Blog::getIsTop, blog.getIsTop());
        }

        if (blog.getTypeId() != null) {
            blogQueryWrapper.lambda().eq(Blog::getTypeId, blog.getTypeId());
        }
        if (blog.getStatus() != null) {
            blogQueryWrapper.lambda().eq(Blog::getStatus, blog.getStatus());
        }

        if (blog.getIsRecommend() != null) {
            blogQueryWrapper.lambda().eq(Blog::getIsRecommend, blog.getIsRecommend());
        }
        if (blog.getAddTime() != null) {
            blogQueryWrapper.lambda().eq(Blog::getAddTime, blog.getAddTime());
        }

        switch (sort) {
            case "addTime":
                blogQueryWrapper.lambda().orderByDesc(Blog::getAddTime);
                break;
            case "clickNum":
                blogQueryWrapper.lambda().orderByDesc(Blog::getClickNum);
            default:
                break;
        }
        return blogQueryWrapper;
    }

    @PostMapping("/admin/uploadBlogImages")
    public Map<String, Object> uploadBlogImages(HttpServletRequest request) throws IOException {
        CommonsMultipartResolver multipartResolver =
                new CommonsMultipartResolver(request.getSession().getServletContext());
        Map<String, Object> map = new HashMap<>();

        if (multipartResolver.isMultipart(request)) {

            MultipartHttpServletRequest mreq = (MultipartHttpServletRequest) request;

            Iterator<String> fileNamesIter = mreq.getFileNames();

            while (fileNamesIter.hasNext()) {

                MultipartFile file = mreq.getFile(fileNamesIter.next());

                if (file != null) {
                    String myFileName = file.getOriginalFilename();

                    if (myFileName.trim() != "") {

                        String fileName = file.getOriginalFilename();

                        String fileBaseName = fileName.substring(0, fileName.lastIndexOf("."));

                        String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();

                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                        String newFileName = df.format(new Date());
                        String fileNames = newFileName + new Random().nextInt(1000000) + "." + fileExt;

                        //获取当前项目的上一级路径
                        String s = System.getProperty("user.dir");
                        //获取当前项目名
                        String contextPath = request.getContextPath();
                        //上传文件的路径
                        String filePath = s +"/"+contextPath + "/upload/" + fileNames;
                        File localFile = new File(filePath);
                        if (!localFile.exists()) {
                            localFile.mkdirs();
                        }
                        file.transferTo(localFile);
                        //这个是获取映射文件夹
                        String parent = request.getScheme()+"://"+request.getServerName()
                                +":"+request.getServerPort()+"/upload/";

                        fileNames = parent + fileNames;
                        map.put("fileName", fileBaseName);
                        map.put("url", fileNames);
                        map.put("uploaded",1);
                        map.put("status", 200);
                    }
                }
            }
        }
        return map;
    }

    /**
     * 上传封面图片
     *
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/admin/uploadBg")
    @SystemLog(description = ConstantUtil.UPLOAD_IMAGES, userType = ConstantUtil.USERTYPE_ADMIN)
    public Map<String, Object> uploadBg(String prarm, HttpServletRequest request) throws Exception {
        CommonsMultipartResolver multipartResolver =
                new CommonsMultipartResolver(request.getSession().getServletContext());
        Map<String, Object> map = new HashMap<>();
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest mreq = (MultipartHttpServletRequest) request;
            Iterator<String> fileNamesIter = mreq.getFileNames();
            while (fileNamesIter.hasNext()) {
                MultipartFile file = mreq.getFile(fileNamesIter.next());
                if (file != null) {
                    String myFileName = file.getOriginalFilename();
                    if (myFileName.trim() != "") {
                        String fileName = file.getOriginalFilename();
                        String fileBaseName = fileName.substring(0, fileName.lastIndexOf("."));
                        String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                        String newFileName = df.format(new Date());
                        String fileNames = newFileName + new Random().nextInt(1000000) + "." + fileExt;
                        //获取当前项目的上一级路径
                        String s = System.getProperty("user.dir");
                        //获取当前项目名
                        String contextPath = request.getContextPath();
                        //上传文件的路径
                        String filePath = s +"/"+contextPath + "/upload/" + fileNames;

                        File localFile = new File(filePath);
                        if (!localFile.exists()) {
                            localFile.mkdirs();
                        }
                        //上传文件的代码
                        file.transferTo(localFile);

                        //这个是获取映射文件夹

                        String parent = request.getScheme()+"://"+request.getServerName()
                                +":"+request.getServerPort()+"/upload/";

                        fileNames = parent + fileNames;
                        map.put("name", fileBaseName);
                        map.put("path", fileNames);
                        map.put("status", 200);
                    }
                }
            }
        }
        return map;
    }

    @PostMapping("/admin/addBlog")
    @SystemLog(description = ConstantUtil.BLOG_ADD, userType = ConstantUtil.USERTYPE_ADMIN)
    public ResultBean<Object> addBlog(String prarm, Blog blog) throws Exception {
        // 将中文的分号转换成英文的分号
        if (blog.getKeyword() != null && blog.getKeyword() != "") {
            blog.setKeyword(SubStringUtil.subKeyword(blog.getKeyword()));
        }
        blog.setAddTime(LocalDateTime.now());
        ResultBean<Object> resultBean = new ResultBean<>();
        if (iBlogService.save(blog)) {
            resultBean.setCode(ResultBean.SUCCESS);
            BlogType blogType = iBlogTypeService.getById(blog.getTypeId());
            blogType.setNum(blogType.getNum() + 1);
            iBlogTypeService.updateById(blogType);
        } else {
            // 0表示：插入失败
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }



    //获取所有类别信息
    public List<BlogType> getType() {
        return iBlogTypeService.list();

    }

    //统计类别下的文章
    public void blogTypeCount(){
        List<BlogType> blogTypes = getType();
        LambdaQueryWrapper<Blog> wrapper;
        for (BlogType blogType : blogTypes) {
            wrapper = new QueryWrapper<Blog>().lambda().eq(Blog::getTypeId,blogType.getId());
            int count = iBlogService.count(wrapper);
            blogType.setNum(count);
            iBlogTypeService.updateById(blogType);
        }
    }
}
